Module-level declarations
Types
Represents a single strategy which can be used to register accounts. It is composed of three parts:
an operation, used to represent the usage of this strategy
a function that extracts
account_details
from the operation argumentsa function that performs any action required by the strategy, given the account and the operation arguments
The transaction that will actually perform the registration will be composed of:
optionally,
evm_signers
the operation defined here
register_account
evm_signers
must contain the signatures of all the EVM participants to the account that will be registered. If the account will be registered with two auth descriptors, all EVM signers of both auth descriptors must add their signatures there. The message to sign can be retrieved by get_register_account_message
. FT signers must simply sign the whole transaction instead. If all signers are FT signers, evm_signers
must be omitted.
The operation will contain some parameters which will be used by account_details
and action
. It should not run any code, except checking requirements to call the operation. One common requirement is that it is being used to register an account, and it can be checked with require_register_account_next_operation
. Most other requirements should be checked in the action
function. The mount name of the operation must be the name of the strategy in the map returned by strategy
.
The register_account
operation will take the name of the previous operation, find out the _strategy
it represents, use the parameters in conjunction with _strategy.account_details
to extract information about the account it needs to create, and call the _strategy.action
function to run the code for the strategy.
Represents information about an account that will be created using a strategy.
Functions
An empty function that can be used if a strategy does not need to perform checks for the account creation.
This should generally not be the function to use, but it can be useful for debugging and testing. Sometimes the _strategy.account_details
function will be forced to have some requirements, and if those are considered enough this function could be passed in _strategy.action
(by leaving action
null in add_strategy
, if used).
If your strategy will use no action, please double check that it does not have requirements that are so loose that they let users create infinite accounts, or your dapp may be vulnerable to DoS attacks.
Used to add new strategies to the dapp. This does not need to be called for FT4-defined strategies.
This function helps avoid a common issue where a strategy is registered with the wrong name. If that happens, many functions of this module will throw errors pointing to that strategy as missing, since they won't be able to find it.
Example usage:
operation my_strategy(
main: accounts.auth_descriptor,
disposable: accounts.auth_descriptor? = null
) {
strategies.require_register_account_next_operation();
}
function account_details(gtv) {
val params = struct<ras_open>.from_gtv(gtv);
val signers = accounts.get_signers(params.main);
return strategies.account_details(
account_id = accounts.get_account_id_from_signers(signers),
main = params.main,
disposable = params.disposable
);
}
function my_custom_logic(accounts.account, gtv) {
// custom logic that the strategy has to follow
}
@extend(strategies.strategy)
function () = strategies.add_strategy(
op = rell.meta(my_strategy),
account_details = account_details(*),
action = my_custom_logic(*)
);
Extendable function that allows the developer to add more functionality to the register_account
function, after the registration happens.
This allows, for example, to add fees on registration or check that any given condition is present after the registration can be completed.
If this function throws an exception, the registration will not happen.
When using the transfer submodule, the strategies defined there already implement extensions of this function, requiring no additional code from the developer. This function should only be extended if functionality that is not found in the predefined strategies is required.
In some cases, creating a new strategy is a better alternative: this function will run on all account registrations, regardless of the strategy they used.
Throws if any extension of this function throws.
Builds a text description of an auth descriptor. It's used to represent the auth descriptor in the account registration message.
Builds a portion of the message that will be used to authorize account registration. This portion gives the information about the auth descriptors that will be added to the newly created account
In a standard usage of the library, this operation would have the mount name of ft4.register_account
, found at external.accounts.registration.register_account
Builds a text description of a multi-sig auth descriptor. It's used to represent the auth descriptor in the account registration message.
Builds a portion of the message that will be used to authorize account registration. This portion gives the information about the operation that called register_account
.
In a standard usage of the library, this operation would have the mount name of ft4.register_account
, found at external.accounts.registration.register_account
Builds a text description of a single-sig auth descriptor. It's used to represent the auth descriptor in the account registration message.
Extendable function that allows the developer to add more functionality to the register_account
function, before the registration happens.
This allows, for example, to add fees on registration or check that any given condition is present before the registration can be completed.
If this function throws an exception, the registration will not happen.
When using the transfer submodule, the strategies defined there already implement extensions of this function, requiring no additional code from the developer. This function should only be extended if functionality that is not found in the predefined strategies is required.
In some cases, creating a new strategy is a better alternative: this function will run on all account registrations, regardless of the strategy they used.
Throws if any extension of this function throws.
Retrieves an account id given the strategy operation, using the account_details
function defined for the _strategy
in question.
Gives a default message used by EVM wallets to authorize the account registration.
Throws if the strategy cannot be found. If strategy_name
is correct, this could also be caused by having misconfigured the registration defined in the function that extends strategy
in such a way that the strategy name and the _strategy.op.mount_name
are not the same value.
Returns a strategy, given the mount name of the operation that defines it.
Throws "MISSING STRATEGY"
if the strategy cannot be found. If strategy_name
is correct, this could also be caused by having misconfigured the registration defined in the function that extends strategy
in such a way that the strategy name and the _strategy.op.mount_name
are not the same value.
Checks whether an operation is a strategy operation that can be used on this chain. Strategy operations not registered through extensions of strategy
will return false, as they won't be usable on this chain.
Registers an account on this chain, using a certain strategy.
Can only be called from an operation.
It will register the account with the account_details
retrieved by _strategy.account_details
, and using the logic found in _strategy.action
.
The new account will have a main auth descriptor given by account_details.main
, and optionally a disposable auth descriptor given by account_details.disposable
It expects all signers of both auth descriptors to have signed this transaction.
Throws if the operation that came just before this one cannot be handled. Common cases are:
the operation is not registered as a strategy operation through extensions of
strategy
the operation has been misconfigured, and its name does not match the operation mount name
Throws if the signature verification is unsuccessful. Common cases are:
evm_signatures
is misconfigured:any of the signers and signatures don't match in the exact order they're found
any of the signatures is null
there's more signatures than signers
a signature from one of the auth descriptor participants is missing:
an EVM signer is specified but the signature is not found in
evm_signatures
an FT signer is specified but the signature is not in the transaction
a signer passed is neither an EVM nor an FT signer (its length does not match either of
core.auth.EVM_ADDRESS_SIZE
andcore.auth.FT_PUBKEY_SIZE
)
Throws if either auth descriptor is invalid. Common cases include:
the main auth descriptor has expiration rules instead of
core.accounts.GTV_NULL
the disposable auth descriptor's expiration rules:
is a complex rule with too many rule components
has already expired
is not the valid GTV representation of a rule
errors with the
args
field:some required flags are missing
in multi-sig auth descriptors, the
required_signatures
field:is 0 or less
is greater than the number of signers
Throws if core.accounts.AUTH_DESCRIPTORS_PER_ACCOUNT_UPPER_BOUND
is set to 1 and account_details.disposable
is not null.
Throws if some conditions added in development through extensions (before_register_account
or after_register_account
) aren't met
Verifies that the next operation in the transaction is an operation that can be used to register accounts. Any operation that is whitelisted to be called after evm_signatures
is considered valid here.
Throws "MISSING REGISTER ACCOUNT"
if:
the next operation is not whitelisted
this is the last operation in the transaction
Throws if the chromia.yml
cannot be parsed for evm_signatures_authorized_operations
, e.g. if some elements are not text or there are duplicates.
Returns a map of all possible strategies used to register accounts on this chain. Can be extended to add custom strategies and make them work seamlessly with the existing register_account
framework.
The map pairs up a strategy operation mount name and the _strategy
struct representing it. The name must be the mount name of _strategy.op
To avoid misconfiguring strategies, it is strongly recommended to add extensions to this function using add_strategy
.
Throws if any extension of this function throws.